﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using SdmxMl.Panels;
using SdmxMl.Common;
using SdmxMl.Manager;
using SdmxMl.Structure;

namespace SdmxMl.UC
{
    public partial class UcFlowRefList : UserControl
    {
        protected DataTable infoTable;
        protected int[] _suggestedSizes = null;

        private bool _isFinal;
        public bool IsFinal
        {
            get { return _isFinal; }
            set
            {
                _isFinal = value;
                EnableGrigButtons();
            }
        }

        public DataTable Table
        {
            get { return infoTable; }
            set 
            { 
                infoTable = value;
                UpdateDataGrid(infoTable);
            }
        }
        private SdmxArtefactType _artefactType;
        public SdmxArtefactType ArtefactType
        {
            get { return _artefactType; }
            set
            {
                _artefactType = value;
            }
        }

        public UcFlowRefList()
        {
            InitializeComponent();
        }

        #region Datagrid

        public void GiveSuggestedSizes(int[] s)
        {
            _suggestedSizes = s;
            SetGridTextWidth();
        }

        private void SetGridTextWidth()
        {
            if (_suggestedSizes != null && infoTable != null)
            {
                for (int i = 0; i < _suggestedSizes.Length && i < dataGridViewInfo.Columns.Count; ++i )
                    dataGridViewInfo.Columns[i].Width = _suggestedSizes[i];
            }
        }

        /// <summary>Update Grid buttons state</summary>
        /// <param name="enable">If true buttons are enabled</param>
        protected void EnableGrigButtons()
        {
            bool enable = _isFinal == false;
            butAdd.Enabled = enable;
            butEdit.Enabled = enable && infoTable != null && infoTable.Rows.Count > 0;
            butRemove.Enabled = enable && infoTable != null && infoTable.Rows.Count > 0 && dataGridViewInfo.SelectedCells.Count > 0;
        }


        private void UpdateDataGrid(DataTable t)
        {
            infoTable = t;
            dataGridViewInfo.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCellsExceptHeaders;
            dataGridViewInfo.DataSource = infoTable;
            SetGridTextWidth();
            EnableGrigButtons();
        }

        private void SelectGridRow(DataGridView dgv, int index)
        {
            if (index < 0)
                return;

            if (dgv.CurrentCell != null)
                dgv.CurrentCell.Selected = false;
            dgv.Rows[index].Cells[1].Selected = true;
            dgv.CurrentCell = dgv.SelectedCells[0];

        }

 
        private DataRow GetSelectedRow()
        {
            DataRow row = null;
            if (infoTable != null && infoTable.Rows.Count > 0)
            {
                int rowIndex = 0;
                if (dataGridViewInfo.SelectedCells.Count > 0)
                    rowIndex = dataGridViewInfo.SelectedCells[0].RowIndex;

                if (rowIndex < infoTable.Rows.Count)
                    row = infoTable.Rows[rowIndex];
            }

            return row;
        }
        private void butEdit_Click(object sender, EventArgs e)
        {
            ArtefactRefBase arRef = MakeArtefactBase();
            if (arRef != null)
            {
                DlgEditReference aDlg = new DlgEditReference(arRef, _artefactType);
                if (aDlg.ShowDialog() == DialogResult.OK)
                {
                    DataRow row = GetSelectedRow();
                    row[1] = arRef.Id;
                    row[2] = arRef.AgencyId;
                    row[3] = arRef.Version;
                    infoTable.AcceptChanges();
                }
            }
        }


        private ArtefactRefBase MakeArtefactBase()
        {
            ArtefactRefBase arRef = null;
            if (infoTable != null && infoTable.Rows.Count > 0)
            {
                DataRow row = GetSelectedRow();
                if (row != null)
                    arRef = new ArtefactRefBase(row[1].ToString(), row[2].ToString(), row[3].ToString());
            }
            return arRef;
        }

        private void butAdd_Click(object sender, EventArgs e)
        {
            DataRow r = infoTable.NewRow();
            r[0] = false;
            r[1] = "Undefined";
            for (int i = 2; i < infoTable.Columns.Count; i++ )
                r[i] = string.Empty;
            infoTable.Rows.Add(r);

            if (dataGridViewInfo.CurrentCell != null)
                dataGridViewInfo.CurrentCell.Selected = false;
            dataGridViewInfo.Rows[infoTable.Rows.Count - 1].Cells[1].Selected = true;
            dataGridViewInfo.CurrentCell = dataGridViewInfo.SelectedCells[0];

            EnableGrigButtons();
        }

        private void butRemove_Click(object sender, EventArgs e)
        {
            int rowIndex = 0;
            if (dataGridViewInfo.SelectedCells.Count > 0)
            {
                rowIndex = dataGridViewInfo.SelectedCells[0].RowIndex;
                if (infoTable.Rows.Count > rowIndex)
                {
                    infoTable.Rows.RemoveAt(rowIndex);
                    EnableGrigButtons();
                    if (infoTable.Rows.Count > 0)
                        SelectGridRow(dataGridViewInfo, infoTable.Rows.Count - 1);
                }
            }

        }

        private void dataGridViewInfo_SelectionChanged(object sender, EventArgs e)
        {
            // Update buttons state
            EnableGrigButtons();
        }

        #endregion //Datagrid

        /// <summary>
        /// Navigate to referred flow or directly to target determined by flow
        /// And for metaflow up to metaset is indicated in flow annotation
        /// </summary>
        /// <param name="sender"></param> <param name="e"></param>
        private void buttonNavigateCodelist_Click(object sender, EventArgs e)
        {
            try
            {
                ArtefactRefBase arRef = MakeArtefactBase();
                bool ctrlKeyPressed = Control.ModifierKeys == Keys.Control;
                if (arRef != null && arRef.IsFilled)
                {
                    object ob = NavigationManager.LocatenavigateProject(_artefactType, arRef.FullIdent, null);
                    if (ob == null)
                        ob = NavigationManager.LocateNavigateWithRegistry(_artefactType, arRef.FullIdent, false, true, null);

                    // If ctrl-Key we just go to flow
                    if (ob != null && ob is IFlowRef && ctrlKeyPressed == false)
                    {
                        // From flow, navigate to DSD or MSD according to reference
                        IFlowRef flowRef = ob as IFlowRef;
                        // If already in memory, navigate otherwhile get from regidtry
                        if (NavigationManager.LocatenavigateProject(flowRef.ReferencedArtefact.Type, flowRef.ReferencedArtefact.FullIdent, null) == null)
                            NavigationManager.LocateNavigateWithRegistry(
                            flowRef.ReferencedArtefact.Type,
                            flowRef.ReferencedArtefact.FullIdent, true, true, null);


                        // Now if URI to artefact load it and go to it
                        MetadataflowType mf = ob as MetadataflowType;
                        if (mf != null && string.IsNullOrEmpty(mf.Uri) == false)
                        {
                            // First load references of MSD
                            //MetadataStructureDefinitionType msd = ReferenceManager.LocateArtefact(SdmxArtefactType.MetadataStructureDefinitions, mf.);



                            ArtefactRefTyped art = UrnManager.UrnToArtefactRefTyped(mf.Uri);

                            if (art != null)
                            {
                                string uri = mf.Uri;
                                // TODO check if flow has an annotation for Last version fetching
                                // if yes, use new proxi method: GetVersionEvolution
                                //    and update flowref for last version
                                if (mf.AnnotationList.GetAnnotationType("LAST_VERSION") != null)
                                {
                                    string vers = SdmxMl.Multiplexor.Mux.Instance.GetLastVersion(art.Type.ToString(), art.FullIdent);
                                    art.Version = vers;
                                    uri = UrnManager.FullIdToUrn(art.Type, art.FullIdent);
                                }

                                UrnParser p = new UrnParser(uri);


                                // If already in memory, navigate otherwhile get from regidtry
                                if (NavigationManager.LocatenavigateProject(art.Type, art.FullIdent, p) == null)
                                    NavigationManager.NavigateWithRegistry(art.Type, art.FullIdent, true, p);
                                // If ok  Select first child if Any
                                if (ReferenceManager.TreeSdmx.SelectedNode != null && ReferenceManager.TreeSdmx.SelectedNode.Nodes.Count > 0)
                                    ReferenceManager.TreeSdmx.SelectedNode = ReferenceManager.TreeSdmx.SelectedNode.FirstNode;

                            }
                        }

                    }
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error");
            }
        }

        

        private void dataGridViewInfo_CellClick(object sender, DataGridViewCellEventArgs e)
        {

        }

    }
}
